/* MailSendExecutor.java:本类功能简介
 * 
 * Created on 2008-3-31
 * 
 * Copyright(C) 2008, by Ambow Research&Development Branch.
 * 
 * Original Author: 初始作者名称
 * Contributor(s): 参与者的名称，参与者名称2，
 * 
 * Changes 
 * -------
 * $Log: MailSendExecutor.java,v $
 * Revision 1.1  2008/04/01 06:12:46  dinghuaining
 * *** empty log message ***
 *
 */


package com.ambow.core.util.email;


import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

public class MailSendService 
{
	private static Logger log = Logger.getLogger(MailSendService.class);
	
	private TaskExecutor taskExecutor;
	
	private JavaMailSender  javaMailSender;	

	private String fromEmail;
	
	private String subject;
	
	public MailSendService(TaskExecutor taskExecutor)
	{
		this.taskExecutor = taskExecutor;
	}
	
	/**
	 * 发送模板类型的邮件。
	 */
	public void sendTemplateMail(String templateName, String toEmail, Map<String, Object> param)
	{
		sendTemplateMail(templateName, toEmail, this.subject,  param);
	}
	
	
	/**
	 * 发送模板类型的邮件。
	 */
	public void sendTemplateMail(String templateName, String toEmail, String subject, Map<String, Object> param)
	{
		List<String> toEmailList = new ArrayList<String>();
		toEmailList.add(toEmail);
		sendTemplateMail(templateName, toEmailList, this.subject,  param);
	}
	
	
	/**
	 * 批量发送模板类型的邮件。
	 */
	public void sendTemplateMail(String templateName, List<String> toEmailList, Map<String, Object> param)
	{
		sendTemplateMail(templateName, toEmailList, this.subject,  param);
	}
	
	/**
	 * 批量发送模板类型的邮件。
	 */
	public void sendTemplateMail(String templateName, List<String> toEmailList, String subject, Map<String, Object> param)
	{		
		
		try {
			VelocityContext context = new VelocityContext(param); 
			
			Template template = Velocity.getTemplate( "template/" + templateName );	

			
			StringWriter sw = new StringWriter();
			
			template.merge(context, sw);
			
			EmailEntity entity = new EmailEntity(this.fromEmail, null, subject, sw.toString());	
			
			log.debug(entity);
			
			for(String to : toEmailList)
			{
				entity.setTo(to);
				sendMimeMail( entity);
			}
			
		} catch (Exception e) {
			log.error("", e);
		} 
		
	}
	
//	/**
//	 * 发送模板类型的邮件。
//	 * param中接收者邮件的KEY为：com.ftuan.Const.KEY_TO_EMAIL_ADDR的值ToEmailAddr
//	 * param中接收者邮件的KEY为：com.ftuan.Const.KEY_TO_EMAIL_ADDR的值ToEmailAddr
//	 */
//	public void sendTemplateMail(String templateName, Map<String,String> param)
//	{		
//		if(log.isDebugEnabled())
//		{
//			log.debug("templateName" + templateName);
//			log.debug(ToStringBuilder.reflectionToString(param));
//		}		
//		
//		String to = param.get(com.ftuan.Const.KEY_TO_EMAIL_ADDR);		
//		String subject = Template.getSubject(templateName);
//		String text = Template.getText(templateName);
//		for(String key : param.keySet())
//		{
//			subject = subject.replaceAll("\\$\\{" + key + "\\}", param.get(key));
//			text = text.replaceAll("\\$\\{" + key + "\\}", param.get(key));
//		}
//		EmailEntity entity = new EmailEntity(fromEmail, to, subject,text);	
//		
//		if(log.isDebugEnabled())
//		{
//			log.debug(entity);
//		}
//		
//		sendMimeMail( entity);
//	}
	
	/**
	 * 发送MIMe类型的邮件
	 */
	public void sendMimeMail(EmailEntity emailEntity)
	{
		if(log.isDebugEnabled())
		{
			log.debug(emailEntity);
		}
		MimeMessage mimeMessage = javaMailSender.createMimeMessage();
		 
		MimeMessageHelper helper;
		try
		{
			helper = new MimeMessageHelper(mimeMessage,true);
			
			helper.setTo(emailEntity.getTo());
			helper.setFrom(emailEntity.getFrom());
			helper.setSubject(emailEntity.getSubject());
			helper.setText(emailEntity.getText(),true);
			
			
		} catch (MessagingException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		taskExecutor.execute(new SendMailTask(mimeMessage));
	}

	/**
	 * 发送简单文本的Email
	 */
	public void sendTextMail(EmailEntity emailEntity)
	{
		if(log.isDebugEnabled())
		{
			log.debug(emailEntity);
		}
		
		SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
		
		simpleMailMessage.setFrom(emailEntity.getFrom());
		simpleMailMessage.setTo(emailEntity.getTo());
		simpleMailMessage.setSubject(emailEntity.getSubject());
		simpleMailMessage.setText(emailEntity.getText());
		
		taskExecutor.execute(new SendMailTask(simpleMailMessage));

	}
	
	
	//内部类,用来发送邮件的 Runnable
	//每次发送邮件都会从线程池中取一个线程, 然后进行发邮件操作
	private class SendMailTask implements Runnable
	{
		//纯文本邮件
		private SimpleMailMessage  simpleMailMessage;
		
		//Mime类型邮件
		private MimeMessage mimeMessage;
		
		public SendMailTask(SimpleMailMessage simpleMailMessage)
		{
			if(mimeMessage == null )
			{
				this.simpleMailMessage = simpleMailMessage;
			}
			
		}
		
		public SendMailTask(MimeMessage mimeMessage)
		{
			if(simpleMailMessage == null )
			{
				this.mimeMessage = mimeMessage;
			}
		}
		public void run()
		{
			try
			{
				if (simpleMailMessage != null)
				{
					javaMailSender.send(simpleMailMessage);
					
				} else if(mimeMessage != null)
				{
					javaMailSender.send(mimeMessage);
				}
				
			}
			catch (Exception e) 
			{
				e.printStackTrace();
			}
			
		}
		
	}
	
	public JavaMailSender getJavaMailSender()
	{
		return javaMailSender;
	}
	
	public void setJavaMailSender(JavaMailSender javaMailSender)
	{
		this.javaMailSender = javaMailSender;
	}

	public String getFromEmail() {
		return fromEmail;
	}

	public void setFromEmail(String fromEmail) {
		this.fromEmail = fromEmail;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

}


